/*
 ********************************************************************************
 * Copyright (c) 2013 Samsung Electronics, Inc.
 * All rights reserved.
 *
 * This software is a confidential and proprietary information of Samsung
 * Electronics, Inc. ("Confidential Information"). You shall not disclose such
 * Confidential Information and shall use it only in accordance with the terms
 * of the license agreement you entered into with Samsung Electronics.
 ********************************************************************************
 */

package adjust_volume;

import java.lang.ref.Reference;
import java.lang.ref.WeakReference;

import android.content.Context;
import android.view.Surface;

import com.samsung.android.sdk.SsdkUnsupportedException;
import com.samsung.android.sdk.gesture.Sgesture;
import com.samsung.android.sdk.gesture.SgestureHand;
import com.samsung.android.sdk.gesture.SgestureHand.Info;
import adjust_volume.Constants;
import adjust_volume.Direction;
import adjust_volume.DrawerOpener;

/**
 * {@link com.srpol.gesturedemo.drawer.DrawerApplier} implementation that uses the Gesture functionality to maniplate
 * the {@link DrawerOpener}.
 */
public class GestureDrawerApplier extends BaseDrawerApplier implements
		SgestureHand.ChangeListener {

	private enum Status {
		UNINITIALIZED, UNSUPPORTED, SUPPORTED
	}

	private final Reference<Context> mContext;
	private Status mStatus;
	private final Sgesture mGesture;
	private SgestureHand mGestureHand;

	public GestureDrawerApplier(Context context, DrawerOpener drawerOpener) {
		super(drawerOpener);

		mGesture = new Sgesture();
		mContext = new WeakReference<Context>(context);
		mStatus = Status.UNINITIALIZED;
	}

	@Override
	public void onChanged(Info gestureInfo) {
		final int angle = gestureInfo.getAngle();
		final Direction direction;
		switch (getDrawerOpener().getRotation()) {
		case Surface.ROTATION_0:
			direction = Direction.computeDirectionFrom(angle);
			break;
		case Surface.ROTATION_90:
			direction = Direction.computeDirectionFrom(angle + 90);
			break;
		case Surface.ROTATION_180:
			direction = Direction.computeDirectionFrom(angle + 180);
			break;
		default:
			direction = Direction.computeDirectionFrom(angle + 270);
			break;
		}
		openDrawerBasedOn(direction);
	}

	public boolean isSupported() {
		if (Status.UNINITIALIZED.equals(mStatus)) {
			if (Constants.IS_AT_LEAST_JELLY_BEAN_MR2) {
				initialize(mContext.get());
			}
		}

		if (Status.SUPPORTED.equals(mStatus)) {
			return true;
		}

		return false;
	}

	/**
	 * Initializes the {@link GestureDrawerApplier}.
	 * 
	 * @param context
	 *            Android {@link Context}
	 */
	public void initialize(Context context) {
		try {
			mGesture.initialize(context);
			mGestureHand = new SgestureHand(context.getMainLooper(), mGesture);
			mStatus = Status.SUPPORTED;
		} catch (IllegalArgumentException e) {
			mStatus = Status.UNSUPPORTED;
		} catch (SsdkUnsupportedException e) {
			mStatus = Status.UNSUPPORTED;
		}
	}

	@Override
	public void enable() {
		mGestureHand.start(Sgesture.TYPE_HAND_PRIMITIVE, this);
	}

	@Override
	public void disable() {
		mGestureHand.stop();
	}

}
